<template>
  <div class="carousel-item-container" ref="container" @mousemove="handleMouseMove" @mouseleave="handleMouseLeave">
    <div class="carousel-img" ref="image" :style="imagePosition">
      <ImageLoader @load="showWords" :src="server_URL + carousel.bigImg" :placeholder="server_URL + carousel.midImg" />
    </div>
    <div class="title" ref="title">{{ carousel.title }}</div>
    <div class="desc" ref="desc">{{ carousel.description }}</div>
  </div>
</template>

<script setup lang="ts">
import { server_URL } from '@/urlConfig'
import { onMounted, ref, onUnmounted, computed } from 'vue'
defineProps(['carousel'])
const titleWidth = ref(0)
const descWidth = ref(0)
const containerSize = ref<any>(null) // 外层容器的尺寸
const innerSize = ref<any>(null) // 里层图片的尺寸
const mouseX = ref(0) // 鼠标的横坐标
const mouseY = ref(0) // 鼠标的纵坐标
const image = ref<any>(null)
const title = ref<any>(null)
const desc = ref<any>(null)
const container = ref<any>(null)
onMounted(() => {
  titleWidth.value = title.value.clientWidth
  descWidth.value = desc.value.clientWidth
  setSize()
  mouseX.value = center.value.x
  mouseY.value = center.value.y
  window.addEventListener('resize', setSize)
})
onUnmounted(() => {
  window.removeEventListener('resize', setSize)
})
const imagePosition = computed(() => {
  if (!innerSize.value || !containerSize.value) {
    return
  }
  const extraWidth = innerSize.value.width - containerSize.value.width // 多出的宽度
  const extraHeight = innerSize.value.height - containerSize.value.height //多出的高度
  const left = (-extraWidth / containerSize.value.width) * mouseX.value
  const top = (-extraHeight / containerSize.value.height) * mouseY.value
  return {
    transform: `translate(${left}px, ${top}px)`
  }
})
const center = computed(() => {
  return {
    x: containerSize.value.width / 2,
    y: containerSize.value.height / 2
  }
})
function showWords() {
  title.value.style.opacity = 1
  title.value.style.width = 0
  // 强制让浏览器渲染一次
  title.value.clientWidth // reflow
  title.value.style.transition = '1s'
  title.value.style.width = titleWidth.value + 'px'

  // 描述也是一样
  desc.value.style.opacity = 1
  desc.value.style.width = 0
  // 强制让浏览器渲染一次
  desc.value.clientWidth // reflow
  desc.value.style.transition = '2s 1s'
  desc.value.style.width = descWidth.value + 'px'
}
function setSize() {
  containerSize.value = {
    width: container.value.clientWidth,
    height: container.value.clientHeight
  }

  innerSize.value = {
    width: image.value.clientWidth,
    height: image.value.clientHeight
  }
}
function handleMouseMove(e: any) {
  const rect = container.value.getBoundingClientRect()
  mouseX.value = e.clientX - rect.left
  mouseY.value = e.clientY - rect.top
}
function handleMouseLeave() {
  mouseX.value = center.value.x
  mouseY.value = center.value.y
}
</script>

<style lang="scss" scoped>
@import '@/styles/var.scss';

.carousel-item-container {
  // background: @dark;
  width: 100%;
  height: 100%;
  color: #fff;
  position: relative;
  overflow: hidden;
}

.carousel-img {
  width: 110%;
  height: 110%;
  position: absolute;
  left: 0;
  top: 0;
  transition: 0.3s;
}

.title,
.desc {
  position: absolute;
  letter-spacing: 3px;
  left: 30px;
  color: #fff;
  text-shadow:
    1px 0 0 rgba(0, 0, 0, 0.5),
    -1px 0 0 rgba(0, 0, 0, 0.5),
    0 1px 0 rgba(0, 0, 0, 0.5),
    0 -1px 0 rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  overflow: hidden;
  opacity: 0;
}

.title {
  top: calc(50% - 40px);
  font-size: 2em;
}

.desc {
  top: calc(50% + 20px);
  font-size: 1.2em;
  color: lighten($gray, 20%);
}
</style>
